#include <iostream>
#include <queue>
using namespace std;

const int kMaxN = 120;
const int kMaxM = 30;
const int kInf = 1e9;

bool can_not_vis[kMaxM][kMaxN];
bool not_use[kMaxM];
int g[kMaxM][kMaxM];
int cost[kMaxN][kMaxN], f[kMaxN][kMaxN];
int dist[kMaxM];

void Dijkstra(int m) {
  priority_queue<pair<int, int>> pq;
  fill(dist, dist + m + 1, kInf);
  dist[1] = 0;
  pq.emplace(-dist[1], 1);
  while (!pq.empty()) {
    int d = -pq.top().first, u = pq.top().second;

    pq.pop();
    if (dist[u] != d) {
      continue;
    }
    for (int v = 1; v <= m; v++) {
      if (g[u][v] != kInf && !not_use[v] && dist[v] > d + g[u][v]) {
        dist[v] = d + g[u][v];
        pq.emplace(-dist[v], v);
      }
    }
  }
}

void GetCost(int n, int m) {
  for (int i = 1; i <= n; i++) {
    fill(cost[i], cost[i] + n + 1, kInf);
  }
  for (int i = 1; i <= n; i++) {
    fill(not_use, not_use + m, false);
    for (int j = i; j <= n; j++) {
      for (int k = 1; k <= m; k++) {
        not_use[k] |= can_not_vis[k][j];
      }
      Dijkstra(m);
      if (dist[m] == kInf) {
        break;
      }
      cost[i][j] = dist[m] * (j - i + 1);
    }
  }
}

int DP(int n, int m, int k) {
  GetCost(n, m);
  for (int i = 0; i <= n; i++) {
    fill(f[i], f[i] + n + 1, kInf);
  }

  int ret = kInf;

  f[0][0] = 0;
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      if (f[i][j] != kInf) {
        for (int next = j + 1; next <= n; next++) {
          f[i + 1][next] = min(f[i + 1][next], f[i][j] + cost[j + 1][next] + k);
        }
      }
    }
  }
  for (int i = 0; i <= n; i++) {
    ret = min(f[i][n], ret);
  }
  return ret - k;
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int n, m, k, e;

  cin >> n >> m >> k >> e;
  for (int i = 1; i <= m; i++) {
    fill(g[i], g[i] + m + 1, kInf);
  }

  for (int i = 0; i < e; i++) {
    int u, v, w;

    cin >> u >> v >> w;
    g[u][v] = g[v][u] = w;
  }

  int d;
  cin >> d;
  for (int i = 0; i < d; i++) {
    int p, a, b;

    cin >> p >> a >> b;
    for (int j = a; j <= b; j++) {
      can_not_vis[p][j] = true;
    }
  }
  cout << DP(n, m, k) << "\n";
  return 0;
}